/*
** Copyright (C) 2009 Joshua Brent Marsh <joshua@icub3d.com>
**  
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation; either version 3 of the License, or
** (at your option) any later version.
**  
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
** GNU General Public License for more details.
**  
** You should have received a copy of the GNU General Public License
** along with this program; if not, write to the Free Software
** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
**  
*/

/* $Id: function_prototypes.c 53 2009-12-24 20:43:05Z joshua@icub3d.com $ */

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#define _GNU_SOURCE

#include <malloc.h>
#include <unistd.h>
#include <string.h>
#include <stdio.h>
#include <string.h>
#include <limits.h>
#include <errno.h>
#include <stdlib.h>
#include <stdint.h>
#include <inttypes.h>
#include <assert.h>

#include "function_prototypes.h"

#include "utilities.h"

void *
copy_int8_t (const void *b)
{
  int8_t *ret = NULL;
  const int8_t *cur = b;

  ret = malloc (sizeof (int8_t));
  if (ret == NULL)
    return NULL;

  *ret = *cur;

  return ret;
}

int
comp_int8_t (const void *a, const void *b)
{
  int8_t first = *(int8_t *) a;
  int8_t second = *(int8_t *) b;

  if (first < second)
    return -1;
  else if (first > second)
    return 1;
  else
    return 0;
}

void
dest_int8_t (void *a)
{
  free (a);
}

void *
copy_int16_t (const void *b)
{
  int16_t *ret = NULL;
  const int16_t *cur = b;

  ret = malloc (sizeof (int16_t));
  if (ret == NULL)
    return NULL;

  *ret = *cur;

  return ret;
}

int
comp_int16_t (const void *a, const void *b)
{
  int16_t first = *(int16_t *) a;
  int16_t second = *(int16_t *) b;

  if (first < second)
    return -1;
  else if (first > second)
    return 1;
  else
    return 0;
}

void
dest_int16_t (void *a)
{
  free (a);
}

void *
copy_int32_t (const void *b)
{
  int32_t *ret = NULL;
  const int32_t *cur = b;

  ret = malloc (sizeof (int32_t));
  if (ret == NULL)
    return NULL;

  *ret = *cur;

  return ret;
}

int
comp_int32_t (const void *a, const void *b)
{
  int32_t first = *(int32_t *) a;
  int32_t second = *(int32_t *) b;

  if (first < second)
    return -1;
  else if (first > second)
    return 1;
  else
    return 0;
}

void
dest_int32_t (void *a)
{
  free (a);
}

void *
copy_int64_t (const void *b)
{
  int64_t *ret = NULL;
  const int64_t *cur = b;

  ret = malloc (sizeof (int64_t));
  if (ret == NULL)
    return NULL;

  *ret = *cur;

  return ret;
}

int
comp_int64_t (const void *a, const void *b)
{
  int64_t first = *(int64_t *) a;
  int64_t second = *(int64_t *) b;

  if (first < second)
    return -1;
  else if (first > second)
    return 1;
  else
    return 0;
}

void
dest_int64_t (void *a)
{
  free (a);
}

void *
copy_uint8_t (const void *b)
{
  uint8_t *ret = NULL;
  const uint8_t *cur = b;

  ret = malloc (sizeof (uint8_t));
  if (ret == NULL)
    return NULL;

  *ret = *cur;

  return ret;
}

int
comp_uint8_t (const void *a, const void *b)
{
  uint8_t first = *(uint8_t *) a;
  uint8_t second = *(uint8_t *) b;

  if (first < second)
    return -1;
  else if (first > second)
    return 1;
  else
    return 0;
}

void
dest_uint8_t (void *a)
{
  free (a);
}

void *
copy_uint16_t (const void *b)
{
  uint16_t *ret = NULL;
  const uint16_t *cur = b;

  ret = malloc (sizeof (uint16_t));
  if (ret == NULL)
    return NULL;

  *ret = *cur;

  return ret;
}

int
comp_uint16_t (const void *a, const void *b)
{
  uint16_t first = *(uint16_t *) a;
  uint16_t second = *(uint16_t *) b;

  if (first < second)
    return -1;
  else if (first > second)
    return 1;
  else
    return 0;
}

void
dest_uint16_t (void *a)
{
  free (a);
}

void *
copy_uint32_t (const void *b)
{
  uint32_t *ret = NULL;
  const uint32_t *cur = b;

  ret = malloc (sizeof (uint32_t));
  if (ret == NULL)
    return NULL;

  *ret = *cur;

  return ret;
}

int
comp_uint32_t (const void *a, const void *b)
{
  uint32_t first = *(uint32_t *) a;
  uint32_t second = *(uint32_t *) b;

  if (first < second)
    return -1;
  else if (first > second)
    return 1;
  else
    return 0;
}

void
dest_uint32_t (void *a)
{
  free (a);
}

void *
copy_uint64_t (const void *b)
{
  uint64_t *ret = NULL;
  const uint64_t *cur = b;

  ret = malloc (sizeof (uint64_t));
  if (ret == NULL)
    return NULL;

  *ret = *cur;

  return ret;
}

int
comp_uint64_t (const void *a, const void *b)
{
  uint64_t first = *(uint64_t *) a;
  uint64_t second = *(uint64_t *) b;

  if (first < second)
    return -1;
  else if (first > second)
    return 1;
  else
    return 0;
}

void
dest_uint64_t (void *a)
{
  free (a);
}

void * 
copy_char (const void *b)
{
  char *ret = NULL;
  const char *cur = b;

  ret = malloc (sizeof (char));
  if (ret == NULL)
    return NULL;

  *ret = *cur;

  return ret;
}

int
comp_char (const void *a, const void *b)
{
  char first = *(char *) a;
  char second = *(char *) b;

  if (first < second)
    return -1;
  else if (first > second)
    return 1;
  else
    return 0;

}

void
dest_char (void *a)
{
  free (a);
}

void * 
copy_float (const void *b)
{
  float *ret = NULL;
  const float *cur = b;

  ret = malloc (sizeof (float));
  if (ret == NULL)
    return NULL;

  *ret = *cur;

  return ret;
}

int
comp_float (const void *a, const void *b)
{
  float first = *(float *) a;
  float second = *(float *) b;

  if (first < second)
    return -1;
  else if (first > second)
    return 1;
  else
    return 0;

}

void
dest_float (void *a)
{
  free (a);
}

void * 
copy_double (const void *b)
{
  double *ret = NULL;
  const double *cur = b;

  ret = malloc (sizeof (double));
  if (ret == NULL)
    return NULL;

  *ret = *cur;

  return ret;
}

int
comp_double (const void *a, const void *b)
{
  double first = *(double *) a;
  double second = *(double *) b;

  if (first < second)
    return -1;
  else if (first > second)
    return 1;
  else
    return 0;

}

void
dest_double (void *a)
{
  free (a);
}

void * 
copy_long_double (const void *b)
{
  long double *ret = NULL;
  const long double *cur = b;

  ret = malloc (sizeof (long double));
  if (ret == NULL)
    return NULL;

  *ret = *cur;

  return ret;
}

int
comp_long_double (const void *a, const void *b)
{
  long double first = *(long double *) a;
  long double second = *(long double *) b;

  if (first < second)
    return -1;
  else if (first > second)
    return 1;
  else
    return 0;

}

void
dest_long_double (void *a)
{
  free (a);
}

void *
copy_string (const void *b)
{
  char *ret = NULL;
  const char *cur = b;

  if (asprintf (&ret, "%s", cur) < 0) 
    {
      int tmp_errno = errno;
      free (ret);
      errno = tmp_errno;
      return NULL;
    }

  return ret;
}

int
comp_string (const void *a, const void *b)
{
  const char *first = a;
  const char *second = b;

  return strcmp (first, second);
}

void
dest_string (void *a)
{
  free (a);
}

ISPair * 
create_ispair (const size_t id, const char *value)
{
  ISPair *nnode;

  nnode = malloc (sizeof (ISPair));
  if (nnode == NULL)
    return NULL;

  nnode->id = id;

  nnode->value = malloc (strlen (value) + 1);
  if (nnode->value == NULL)
    {
      int tmp_errno = errno;
      free (nnode);
      errno = tmp_errno;
      return NULL;
    }
  strcpy (nnode->value, value);

  return nnode;
}

void * 
copy_ispair (const void *b)
{
  ISPair *ret;
  const ISPair *cur = b;

  ret = malloc (sizeof (ISPair));
  if (ret == NULL)
    return NULL;

  ret->id = cur->id;

  ret->value = malloc (strlen (cur->value) + 1);
  if (ret->value == NULL)
    {
      int tmp_errno = errno;
      free (ret);
      errno = tmp_errno;
      return NULL;
    }
  strcpy (ret->value, cur->value);

  return ret;
}

int
comp_ispair (const void *a, const void *b)
{
  const ISPair *first = a;
  const ISPair *second = b;

  if (first->id < second->id)
    return -1;
  else if (first->id > second->id)
    return 1;
  else
    return 0;
}

void
dest_ispair (void *a)
{
  ISPair *first = a;

  free (first->value);
  free (first);
}

SSPair * 
create_sspair (const char *name, const char *value)
{
  SSPair *nnode;

  nnode = malloc (sizeof (SSPair));
  if (nnode == NULL)
    return NULL;

  nnode->name = malloc (strlen (name) + 1);
  if (nnode->name == NULL)
    {
      int tmp_errno = errno;
      free (nnode);
      errno = tmp_errno;
      return NULL;
    }
  strcpy (nnode->name, name);

  nnode->value = malloc (strlen (value) + 1);
  if (nnode->value == NULL)
    {
      free (nnode->name);
      free (nnode);
      return NULL;
    }
  strcpy (nnode->value, value);

  return nnode;
}

void * 
copy_sspair (const void *b)
{
  SSPair *ret;
  const SSPair *cur = b;

  ret = malloc (sizeof (SSPair));
  if (ret == NULL)
    return NULL;

  ret->name = malloc (strlen (cur->name) + 1);
  if (ret->name == NULL)
    {
      int tmp_errno = errno;
      free (ret);
      errno = tmp_errno;
      return NULL;
    }
  strcpy (ret->name, cur->name);

  ret->value = malloc (strlen (cur->value) + 1);
  if (ret->value == NULL)
    {
      int tmp_errno = errno;
      free (ret->name);
      free (ret);
      errno = tmp_errno;
      return NULL;
    }
  strcpy (ret->value, cur->value);

  return ret;
}

int
comp_sspair (const void *a, const void *b)
{
  const SSPair *first = a;
  const SSPair *second = b;

  return strcmp (first->name, second->name);
}

void
dest_sspair (void *a)
{
  SSPair *first = a;

  free (first->name);
  free (first->value);
  free (first);
}
